package com.ruolin.micro.gateway.server.utils;

import com.ruolin.micro.gateway.server.metadata.ParameterMetadata;
import com.ruolin.micro.gateway.server.metadata.Type;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

public class ParameterUtils {
    private ParameterUtils() {
        throw new AssertionError("No com.ruolin.micro.gateway.server.utils.ParameterUtils instances for you!");
    }

    public static List<ParameterMetadata> getParameters(String queryString) {
        if (StringUtils.isEmpty(queryString)) {
            throw new IllegalArgumentException("queryString is null");
        }

        String transform = transform(queryString);
        String[] parameterArray = transform.split("&");
        List<ParameterMetadata> parameterMetadata = new ArrayList<>();
        for (int i = 0; i < parameterArray.length; i++) {
            String[] factors = parameterArray[i].split("=");
            parameterMetadata.add(new ParameterMetadata(factors[0], factors[1], i));
        }
        if (parameterMetadata.size() == 1) {
            return parameterMetadata;
        }
        Map<String, List<ParameterMetadata>> namedParameterMetadata = parameterMetadata.stream().collect(Collectors.groupingBy(ParameterMetadata::getName));
        List<ParameterMetadata> mergingParameterMetadata = parameterMetadata.stream()
                .filter(m -> (namedParameterMetadata.containsKey(m.getName()) && namedParameterMetadata.get(m.getName()).size() > 1))
                .collect(Collectors.toList());
        Collections.sort(mergingParameterMetadata, Comparator.comparing(ParameterMetadata::getIndex));
        if (!mergingParameterMetadata.isEmpty()) {
            ParameterMetadata minParameterMetadata = mergingParameterMetadata.get(0);
            Object parameterValue = minParameterMetadata.getValue();
            List<Object> parameterValues = new ArrayList<>();
            parameterValues.add(parameterValue);
            for (ParameterMetadata metadata : mergingParameterMetadata) {
                parameterValues.add(metadata.getValue());
            }
            parameterMetadata.removeAll(mergingParameterMetadata);
            minParameterMetadata.setValue(parameterValues);
            parameterMetadata.add(minParameterMetadata);
        }
        return parameterMetadata;
    }

    public static String transform(String queryString) {
        String decodeUrl = null;
        //将带汉字的encodeURI编码转换成字节，然后用UTF-8格式对字节解码
        try {
            decodeUrl = URLDecoder.decode(queryString, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return decodeUrl;
    }

    public static Object[] buildParameter(List<ParameterMetadata> parameterMetadataList) {
        Collections.sort(parameterMetadataList, Comparator.comparing(ParameterMetadata::getIndex));

        Object[] args = new Object[parameterMetadataList.size()];
        for (int i = 0; i < parameterMetadataList.size(); i++) {
            args[i] = parameterMetadataList.get(i).getValue();
        }
        return args;
    }

    public static Map<String, Object> buildParameterMap(List<ParameterMetadata> parameterMetadataList) {
        Collections.sort(parameterMetadataList, Comparator.comparing(ParameterMetadata::getIndex));
        final Map<String, Object> parameterMap = new LinkedHashMap<>();
        parameterMetadataList.forEach(m -> {
            parameterMap.put(m.getName(), m.getValue());
        });

        return parameterMap;
    }

    public static void main(String[] args) {
        String str = "/a/b/c";
        int i = StringUtils.lastIndexOf(str, "/");
        String query = "name=张三&age=18&sex=男&a=1&a=2&a=3";
        String[] split = query.split("&");
        System.out.println(split);
        for (String s : split) {
            String[] split1 = s.split("=");
            System.out.println(split1);
        }
        List<ParameterMetadata> parameters = getParameters("name=张三");
        System.out.println(parameters);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", "张三");
        paramMap.put("age", 18);
    }

    public static Set<String> getFields(Type type) {
        return type.getProperties().keySet();
    }

    public static Map<String, Object> convertObjectMap(Map<String, Object> parameterMap, Map<String, Object> fieldMap) {
        for (Map.Entry<String, Object> entry : fieldMap.entrySet()) {
            if (parameterMap.containsKey(entry.getKey())) {
                fieldMap.put(entry.getKey(), parameterMap.get(entry.getKey()));
                parameterMap.remove(entry.getKey());
            }
        }
        return fieldMap;
    }
}
